<template>
  <div class="lookOver_box">
    <header></header>
    <main>
      <div class="tree">
        <div class="not_have" v-if="tree_data.length === 0">暂无目录</div>
        <TreeMenu
          v-else
          :data="tree_data"
          :activeNode="active_node"
          @node-click="node_click"
        ></TreeMenu>
      </div>

      <div class="blog_box" v-html="html_str" ref="html_con"></div>
    </main>
  </div>
</template>

<script setup>
import { useRoute } from "vue-router";
import { onMounted, ref, nextTick } from "vue";
import { get_blog } from "@/axios/home/index.js";
import TreeMenu from "@/components/tree/TreeMenu.vue";
import Prism from "prismjs";
//代码高亮样式
// import "prismjs/themes/prism.css";
import "prismjs/themes/prism-okaidia.css";
//左侧行号js+css
import "prismjs/plugins/line-numbers/prism-line-numbers";
import "prismjs/plugins/line-numbers/prism-line-numbers.css";
//右上角按钮js+css
import "prismjs/plugins/toolbar/prism-toolbar.min.js";
import "prismjs/plugins/toolbar/prism-toolbar.min.css";
//自动链接js+css
import "prismjs/plugins/autolinker/prism-autolinker.min.js";
import "prismjs/plugins/show-language/prism-show-language.min.js";
// 复制代码
import "prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js";
// 代码括号高亮+代码括号显示标识符
import "prismjs/plugins/match-braces/prism-match-braces.min.js";
import "prismjs/plugins/match-braces/prism-match-braces.min.css";

const route = useRoute();

const id = ref(route.query.id);
const html_str = ref("");
const html_con = ref(null);
const tree_data = ref([]);
// 新增：使用 ref 来跟踪当前激活的节点
const active_node = ref(null);

onMounted(async () => {
  let blog_data = await get_blog({
    id: id.value,
  });
  html_str.value = blog_data.data.blog;
  nextTick(() => {
    let preBlocks = document.querySelectorAll("pre");
    preBlocks.forEach((preBlock) => {
      preBlock.setAttribute("lang", "zh-Hans-CN");
      preBlock.setAttribute("data-prismjs-copy", "复制");
      preBlock.setAttribute("data-prismjs-copy-error", "复制失败,刷新再试");
      preBlock.setAttribute("data-prismjs-copy-success", "已复制");

      // pre元素 的class
      preBlock.className += " line-numbers"; // 显示行号
      // code元素的class
      preBlock.querySelector("code").className +=
        " match-braces no-brace-hove rainbow-braces"; //括号颜色+括号高亮
    });
    Prism.highlightAll(); // 全局代码高亮

    tree_data.value = build_tree(html_con.value);
  });
});

// 处理节点点击事件
const node_click = (node) => {
  active_node.value = node.id; // 更新高亮节点
  node.tag.scrollIntoView({ behavior: 'smooth', block: 'start' });
};

const build_tree = (dom) => {
  // 判断传入的参数是否是一个 DOM 节点
  if (!(dom instanceof Node) || dom.nodeType !== Node.ELEMENT_NODE) {
    console.error("传入的参数不是一个有效的 DOM 元素");
    return [];
  }

  // 判断 DOM 中是否包含标题标签（H1, H2, H3, H4, H5）
  if (!dom.querySelector("h1, h2, h3, h4, h5")) {
    console.error("传入的 DOM 中没有标题标签（H1, H2, H3, H4, H5）");
    return [];
  }

  const tree = [];
  const currentNodes = {}; // 用于存储当前各级标题的节点
  let idCounter = 0; // 用于生成唯一 id 的计数器

  const traverse = (node) => {
    if (node.nodeType === Node.ELEMENT_NODE) {
      const tagName = node.tagName;
      const textContent = node.textContent.trim();

      // 判断是否是标题标签
      if (/^H[1-5]$/.test(tagName)) {
        const level = parseInt(tagName.slice(1), 10); // 获取标题的层级（1-5）
        const newNode = {
          id: `node-${idCounter++}`, // 生成唯一 id
          tag: node,
          label: textContent,
          children: [],
        };

        // 根据层级找到父节点
        let parentNode = null;
        for (let i = level - 1; i >= 1; i--) {
          if (currentNodes[`H${i}`]) {
            parentNode = currentNodes[`H${i}`];
            break;
          }
        }

        // 将新节点添加到父节点的 children 中
        if (parentNode) {
          parentNode.children.push(newNode);
        } else {
          tree.push(newNode); // 如果没有父节点，则作为根节点
        }

        // 更新当前层级节点
        currentNodes[`H${level}`] = newNode;

        // 清空更低层级的节点
        for (let i = level + 1; i <= 5; i++) {
          delete currentNodes[`H${i}`];
        }
      }
    }

    // 递归遍历子节点
    node.childNodes.forEach((child) => traverse(child));
  };

  traverse(dom);
  return tree;
};
</script>

<style scoped lang="less">
.lookOver_box {
  width: 100%;
  min-height: 100vh;
  background-color: rgb(242, 242, 242);

  header {
    width: 100%;
    height: 80px;
    border-bottom: 1px solid @ls;
    background-color: @bs;
    box-sizing: border-box;
  }

  main {
    width: 1200px;
    min-width: 1200px;
    margin: 10px auto 0;
    display: flex;
    height: calc(100vh - 90px);
    min-height: calc(100vh - 90px);

    .tree {
      width: 200px;
      background-color: @bs;
      height: 100%;
      .not_have {
        height: 60px;
        line-height: 60px;
        font-size: 20px;
        text-align: center;
        font-weight: 900;
      }
    }
    .blog_box {
      width: 990px;
      margin: 0 0 0 10px;
      height: 100%;
      overflow-y: auto;
      // 编辑器复制按钮+代码名称美化
      .toolbar-item > button,
      .toolbar > .toolbar-item > span {
        background: rgb(67, 67, 67) !important;
        color: white !important;
        box-shadow: none !important;
        border-radius: 3px !important;
        padding: 2px 8px !important;
      }

      .toolbar > .toolbar-item > span {
        padding: 3.6px 5px !important;
      }

      .toolbar-item > button {
        margin: 0 6px;
        cursor: pointer;

        &:hover {
          background: rgb(67, 67, 67) !important;
        }

        &:active {
          background: black !important;
        }
      }
    }
  }
}
</style>
